package org.ucas.faker.web.utils.tech;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PatentFeaturize3 {
	private List<String> features = null;
	private List<String> effects = null;
	private List<Rule> frules = null;
	private List<Rule> erules = null;
	
	private PatentFeaturize3(){
		features = new ArrayList<>();
		effects = new ArrayList<>();
		frules = new ArrayList<>();
		erules = new ArrayList<>();
		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream("feature.rule");

			InputStreamReader read = new InputStreamReader(is);// 考虑到编码格式
			BufferedReader featureReader = new BufferedReader(read);
			String lineTxt = null;
			while ((lineTxt = featureReader.readLine()) != null) {
				// System.out.println(lineTxt);
				features.add(lineTxt);
			}
		} catch (Exception e) {
			System.out.println("Error reading feature.rule");
			e.printStackTrace();
		}
		
		
		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream("effect.rule");
			// File file=new File("effect.rule");
			InputStreamReader read = new InputStreamReader(is);// 考虑到编码格式
			BufferedReader featureReader = new BufferedReader(read);
			String lineTxt = null;
			while ((lineTxt = featureReader.readLine()) != null) {
				// System.out.println(lineTxt);
				effects.add(lineTxt);
			}
			read.close();
		} catch (Exception e) {
			System.out.println("Error reading effect.rule");
			e.printStackTrace();
		}

		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream("effect_structure.rule");
			InputStreamReader read = new InputStreamReader(is);// 考虑到编码格式
			BufferedReader featureReader = new BufferedReader(read);
			String lineTxt = null;
			while ((lineTxt = featureReader.readLine()) != null) {
				// System.out.println(lineTxt);
				erules.add(new Rule(lineTxt));
			}
			read.close();
		} catch (Exception e) {
			System.out.println("Error reading effect_structure.rule");
			e.printStackTrace();
		}

		try {
			InputStream is = this.getClass().getClassLoader().getResourceAsStream("feature_structure.rule");

			// File file=new File("feature_structure.rule");

			InputStreamReader read = new InputStreamReader(is);// 考虑到编码格式
			BufferedReader featureReader = new BufferedReader(read);
			String lineTxt = null;
			while ((lineTxt = featureReader.readLine()) != null) {
				// System.out.println(lineTxt);
				frules.add(new Rule(lineTxt));
			}
			read.close();
		} catch (Exception e) {
			System.out.println("Error reading feature_structure.rule");
			e.printStackTrace();
		}
	}
	
	private static PatentFeaturize3 singleton = null;
	
	public static PatentFeaturize3 getInstance(){
		if(singleton==null){
			singleton = new PatentFeaturize3();
		}
		return singleton;
		
	}

	private Map<String,List<String>> featurize(String text, List<String> keywords,String sentProps){
		Map<String,List<String>> resultMap = new HashMap<>();
		List<String> lfeatures = new ArrayList<>();
		List<String> leffects = new ArrayList<>();
		List<String> lunknown = new ArrayList<>();
		
        String split_string="；|。|;";
        String [] sent_blank = text.split(split_string);
        
        //System.out.println("\nSent without Prop");
        //for(String s: sent_blank) System.out.println(s);
        
        String [] sent_prop = sentProps.split("\\|[；。;\\?\\(]{1,2}/[a-z]{1,4}\\|");
        
        //System.out.println("\nSent with Prop");
        //for(String s : sent_prop)  	System.out.println(s);
        
        
        List<SentenceWithProperty> lsent = new ArrayList<>();
        for(int i=0;i<sent_blank.length;i++){
        	lsent.add(new SentenceWithProperty(sent_blank[i],sent_prop[i]));
        }
        
		List<Integer> sen_pos = new ArrayList<>();
		for(String key : keywords){
			sen_pos.clear();
			//System.out.println("un\t:"+key);
			for(int i=0;i<sent_blank.length;i++){
				if(sent_blank[i].indexOf(key)!=-1) {
					sen_pos.add(i);
					//System.out.println(sent_blank[i]);
				}
			}
			//System.out.println();
			if(sen_pos.size()==0){
				//TODO				
				continue;
			}
			//判断属于特征还是功效
			int num_fea = 0;
			int num_eff = 0;
			List<Integer> lfea = new ArrayList<>();
			List<Integer> leff = new ArrayList<>();
			for(int i:sen_pos){
				String sent = sent_blank[i];
				//System.out.println("##"+sent);
				for (String fea : features){
					if(sent.indexOf(fea)!=-1){
						//System.out.println("feature\t:"+key);
						//lfeatures.add(key);
						if(!lfea.contains(i)) lfea.add(i);
						num_fea++;
					}
				}				
				for(String eff : effects){
					if(sent.indexOf(eff)!=-1){
						//System.out.println("effects\t:"+key);
						//leffects.add(key);
						if(!leff.contains(i)) leff.add(i);
						num_eff++;
					}
				}
			}
			
			//System.out.println("\n#"+key+" ("+num_fea+" , "+num_eff+")");
			
			//其中一个为0,只能二选一
			if((num_fea!=0 && num_eff==0)||num_fea-num_eff>=3){//feature出现次数比effect出现次数多3
				lfeatures.add(key);
			}else if(num_fea==0 && num_eff!=0||num_eff>num_fea){
				leffects.add(key);
			}else if(num_fea+num_eff!=0){//两个均存在
				//features
				int lfea_distance = 1000;
				int leff_distance = 1000;
				for(int i : lfea){
        			List<String> before = new ArrayList<>();
        			List<Integer> bpos = new ArrayList<>();
        			List<String> after = new ArrayList<>();
        			List<Integer> apos = new ArrayList<>();

        			List<String> keyCixing = new ArrayList<>();
            		int pos = sent_blank[i].indexOf(key);
        			//System.out.println("Key"+key+"\tPos " +pos);
            		if(pos>-1){
            			lsent.get(i).getBeforeAfter(pos, pos+key.length(),keyCixing, before, bpos, after, apos);
            			//System.out.println(pos+" "+swp.sentence);
            			//for(String bs : before) System.out.print(bs+" ");
            			//System.out.print("---");
            			//for(String bs : after) System.out.print(bs+" "); 
            			//System.out.println();
            			//for(String cixing : keyCixing) System.out.print(cixing+" ");
            			//System.out.println("---");

            			//System.out.println("\nFeature rules");
            			for (Rule r: frules){
            				int distance = r.RuleMatch(before, bpos, after, apos);
        					//System.out.print(key+" dis "+distance+"\t");
            				if(distance>0){
            					if(distance<lfea_distance) lfea_distance = distance;
            					//System.out.println("feature  "+key+" dis "+distance);
            					continue;
            				}
            			}
            		}
            	}
				//effect
				for(int i : leff){
	    			List<String> before = new ArrayList<>();
	    			List<Integer> bpos = new ArrayList<>();
	    			List<String> after = new ArrayList<>();
	    			List<Integer> apos = new ArrayList<>();
	
	    			List<String> keyCixing = new ArrayList<>();
	        		int pos = sent_blank[i].indexOf(key);
	    			//System.out.println("Key"+key+"\tPos " +pos);
	        		if(pos>-1){
	        			lsent.get(i).getBeforeAfter(pos, pos+key.length(),keyCixing, before, bpos, after, apos);

	        			//System.out.println(pos+" "+swp.sentence);
	        			//for(String bs : before) System.out.print(bs+" ");
	        			//System.out.print("---");
	        			//for(String bs : after) System.out.print(bs+" "); 
	        			//System.out.println();
	        			//for(String cixing : keyCixing) System.out.print(cixing+" ");
	        			//System.out.println("---");
	        			for (Rule r: erules){
	        				int distance = r.RuleMatch(before, bpos, after, apos);
	    					//System.out.print(key+" dis "+distance+"\t");
	        				if(distance>0){            					
	        					if(distance<leff_distance) leff_distance = distance;
	        					//System.out.println("effect  "+key+" dis "+distance);
	        					continue;
	        				}
	        			}
	        			
	        		}
				}

    			if(leff_distance<lfea_distance) leffects.add(key);
    			else lfeatures.add(key);
				
			}
			//not classified
			else if(num_fea+num_eff==0){
				lunknown.add(key);
				//add other rules
				//System.out.println("unkown\t:"+key);
			}
			
		}
		
		resultMap.put("feature", lfeatures);
		resultMap.put("effect", leffects);
		resultMap.put("unknown", lunknown);
		
		return resultMap;
	}
	
	private void displayResult(Map<String,List<String>> map){
		List<String> l = map.get("feature");
		System.out.print("Feature: ");
		for(String s : l){
			System.out.print(s+"\t");
		}
		
		l = map.get("effect");
		System.out.print("\nEffect: ");
		for(String s : l){
			System.out.print(s+"\t");
		}
		
		l = map.get("unknown");
		System.out.print("\nUnknown: ");
		for(String s : l){
			System.out.print(s+"\t");
		}
		
	}
	/*
	private void TestFromFile(String filepos){
		int order = 1;
		try {
        File file=new File(filepos);
        if(file.isFile() && file.exists()){ //判断文件是否存在
            InputStreamReader read = new InputStreamReader(
            new FileInputStream(file));//考虑到编码格式
            BufferedReader featureReader =  new BufferedReader(read);
            String lineTxt = null;
            while((lineTxt = featureReader.readLine()) != null){
                //System.out.println(lineTxt);
            	System.out.println("order "+order);
            	order++;
                String [] oneline = lineTxt.split("  ");
                String [] splits = oneline[1].split("##");
                
                System.out.println(oneline[0]);
                //featurizeString(splits[0]);
                List<String> l = featurizeString(oneline[0]);
        		//System.out.println(l.get(0));
        		//System.out.println(l.get(1));
                lineTxt = featureReader.readLine();
                //System.out.println("\n");
                //break;
            }
            read.close();
    }else{
        System.out.println("Error finding feature.rule");
    }
    } catch (Exception e) {
        System.out.println("Error reading feature.rule");
        e.printStackTrace();
    }
		
	}
	*/

	public List<String> featurizeString(String abstra,List<String> lkeyword,String sent_prop){
		//System.out.println("\n****\n"+abstra);
		Map<String,List<String> > map = null;
		List<String> res = new ArrayList<String>();
		try{
			map = featurize(abstra,lkeyword,sent_prop);
		}catch(Exception e){
			System.out.println("Exception!!!");
			res.add("");res.add("");
			return res;
		}
		
		String feature="";
		if(map.get("feature")!=null){
			for(String s:map.get("feature")){
				feature += s+"#";
			}
			if(feature.length()<=0) res.add("");
			else res.add(feature.substring(0, feature.length()-1));
			
		}
		
		String effect="";
		if(map.get("effect")!=null){
			for(String s:map.get("effect")){
				effect += s+"#";
			}
			if(effect.length()<=0) res.add("");
			else res.add(effect.substring(0, effect.length()-1));			
		}
		
		return res;
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PatentFeaturize3 pf = PatentFeaturize3.getInstance();
		//pf.TestDirectlyFromFile("testcase");
		
		//String abs = "本发明提供一种蓄电元件用电极以及蓄电元件，其在制造时或使用时具有短路防止及其他的功能的层以及/或者活性物质层难以剥离脱落。蓄电元件用电极(10)具有：集电体箔(11)；活性物质层(12)，其形成于集电体箔(11)的至少一个表面上；以及高电阻层(40)，其形成于集电体箔(11)的表面上，并且与活性物质层(12)相邻，所述蓄电元件用电极(10)在活性物质层(12)和高电阻层(40)的界面(50)的至少一部分形成有含有所述两个层(12、40)的组成的混合相(51)。活性物质层(12)和高电阻层(40)的界面(50)具有混合相(51)，由此相邻的两个层(12、40)的连接变坚固。";
		//List<String> l = pf.featurizeString(abs);
		//System.out.print(abs);
		
		/*
		List<String> l = pf.featurizeString(abs);
		System.out.println(l.get(0));
		System.out.println(l.get(1));
		*/
	}
	

}
